
// console.log(typeof 123)
// console.log(typeof('123'))
// console.log(typeof(true))

// console.log(typeof [])
// console.log(typeof {})
// console.log('=============')
// console.log(Array.isArray([]))
// console.log(Array.isArray({}))


// console.log([] instanceof Object)
// console.log({} instanceof Object)

// console.log([] instanceof Array)
// console.log({} instanceof Array) false

// console.log(实例 instanceof 创建实例的函数)

// function f(option) {}

/*
let fn = []
let fn = {}
let fn = function () {} // object
fn.aaa = 'AAAAA'
console.log(fn)
console.log(fn.aaa)*/
// fn()


// 构造对象的函数
/*
function Person(uname) {
  this.name = uname
  this.age = 24
}
//
let p1 = new Person('张三')
let p2 = new Person('李四')*/

// console.log(p1)
// console.log(p2)

// console.log(Person)
// console.log(Object)
// console.log(Array)
// console.log(Function)

/*
// 构造函数
function Person(uname) {
  this.name = uname
  this.age = 24
}
Person.prototype.sayHi = function () {
  console.log('hi')
}
Person.prototype.color = 'red'
// console.log(Person.prototype)
console.log(Person)*/
// console.log(Person.prototype.constructor)
// new 一个实例
// let p1 = new Person('张三')
// let p2 = new Person('李四')
// 实例的__proto__(隐式原型) 等于 构造函数的 prototype
// 实例的__proto__指向该构造函数的 prototype
// console.log(p1.__proto__ === Person.prototype) // true
// console.log(p2.__proto__ === Person.prototype) // true

// console.log(p1.hasOwnProperty('color'))
// console.log(p1.hasOwnProperty('name'))

// p1.color
// p1.name
// console.log(p1)

// console.log(p1.color)
// console.log(p2)

// let arr = ['hello', 'world']
// arr[0]
// arr.sort()

// console.log(Object.prototype) // {}
// console.log(Array.prototype) // []
/*Array.prototype.myFind = function () {
  console.log(this)
}*/
// console.log(Array.prototype)

/*
// eval('alert(123)')
let x
console.log(x)
x = 10
console.log(x)
console.log(this)
document.documentElement.onclick = function () {
  let x = 22
  console.log(this)
}
let f1 = () => {}*/

/*document.documentElement.onclick = function (a, b, c) {
  console.log(arguments)
  let x = 22
  console.log(this)
}*/

// 函数作为构造函数时 this 是即将 new 出的那个对象
// 谁调用这个方法谁就是this
// call, apply（只有在调用时用） 调用方法时就是传入的对象的值（绑定this）
// bind 返回一个新的方法，永远指向bind绑定的对象
// 箭头函数在哪定义谁就是this
/*
function Person(uname) {
  this.name = uname
  this.age = 24
  // console.log(this)
}
let p1 = new Person()
// console.log(p1)
let obj = {
  a: 'A',
  b: 'B',
  fn: function () {
    console.log(this)
  },
  test: function () {
    /!*function f() {
      console.log(this)
    }*!/
    //
    let f = () => {
      console.log(this)
    }
    f()
  }
}*/
// obj.fn()
// let f2 = obj.fn
// f2() // window
// f2.call(obj)
// f2.apply(obj)
// let f2 = obj.fn.bind(123)
// f2()
// obj.test()

/*
$('.btn').click(() => {
  // this
})*/


// [1, 2, 3]
// [1, 2, 3, 123]

// 队列
// 堆栈

/*
* 闭包（跨作用域访问变量）
* 1. 函数嵌套
* 2. 内部函数使用了外部的数据或者变量或者函数
* */

function fn() {
  let max = 10
  function bar() {
    return max++
  }
  return bar
}

let bar = fn()
// fn()()
console.log(bar())
bar = null

bar = fn()
console.log(bar())
bar = null

bar = fn()
console.log(bar())
console.log(bar())
console.log(bar());

(function f() {
  for (let i = 0; i < 10; i++) {
    console.log(i)
  }
})()

/*

for (let i = 0; i < 11; i++) {
  console.log(i)
}
console.log(i)*/

